import re
from docx.oxml.text.paragraph import CT_P
from docx.oxml.table import CT_Tbl

from docx.text.paragraph import Paragraph
from docx.table import Table

from docx import Document

import json

fangan1 = dict()
with open("dagang6.json", encoding='UTF-8') as f:
    fangan1 = json.load(f)


def find(pattern, pt, offset=0):
    def _find_keyword(pattern, pt, offset=0):
        if pattern:
            if isinstance(pt, Paragraph):
                g = re.search(pattern=pattern, string=pt.text)
                if g:
                    for v in g.groupdict().values():
                        return v, offset
                    return '', offset
        return None
    if isinstance(pattern, str):  # "str"
        return _find_keyword(pattern, pt, offset)
    elif isinstance(pattern, dict):  # {"1":0,"2":0}
        for ep in pattern.keys():
            return find(ep, pt, pattern.get(ep, offset))
    elif isinstance(pattern, list):  # [dict()]  or ["str"]
        for ep in pattern:
            return find(ep, pt)
    return None


def find_set_value(pattern, attrname, content):
    # print(self.content)

    for pt in content.content:

        value = find(pattern, pt)
        if value != None:
            if hasattr(content, attrname):
                setattr(content, attrname, value[0])
                print(attrname, '=', [value[0]])
            else:
                raise AttributeError('需要先定义属性')
            return value[0]
    return None


def printpt(pts, level=0):
    lenpts = len(pts)
    for line, pt in enumerate(pts):
        # if line > 9:
        #     if line < lenpts - 10:
        #         print('.', end='')
        #         continue
        #     if lenpts > 20 and line == lenpts - 10:
        #         print('.')
        if isinstance(pt, Paragraph):
            print('  ' * (level+2), [line+1],  pt.text[:50])
        else:
            print('  ' * (level+2), [line+1],  type(pt))


class Section(object):
    def __init__(self, parent, content=[], sectionconfig={}, level=0, name='文档', loseline=0):
        super().__init__()
        self.parent = parent
        self.content = content if isinstance(
            content, list) else self.readcontent(content)
        self.sectionconfig = sectionconfig
        self.name = name
        self.line = -1
        self.loseline = loseline
        self.level = level + 1
        self.sections = [x for x in sectionconfig.keys()
                         if isinstance(sectionconfig.get(x), dict) and 'enter' in sectionconfig.get(x).keys()]
        self.sectionsvalue = list()
        self.attributes = [x for x in sectionconfig.keys()
                           if not isinstance(sectionconfig.get(x), dict) and x not in ['enter', 'loseline', 'leave']]
        self.attributesvalue = list()

        print('  '*self.level,  self.level,
              self.name, '共%s行' % len(self.content))
        # if self.attributes:
        #     print(self.attributes)
        self.readattributes()
        # if self.sections:
        #     print(self.sections)
        self.readsections()

    def readcontent(self, filename):
        content = []
        body = Document(filename).element.body
        for line, b1 in enumerate(body.iterchildren()):
            if line > 1000:
                break
            if isinstance(b1, CT_P):
                content.append(Paragraph(b1, body))
            elif isinstance(b1, CT_Tbl):
                content.append(Table(b1, body))
            else:
                print(line, '未处理类型 '*5, type(b1))
        return content

    def append(self, content):
        self.content.append(content)

    def length(self):
        length = 0
        for x in self.sectionsvalue:
            for xx in x:
                length += xx.length()
        return length if length > 0 else len(self.content)
        # return  sum([xx.length() for xx in (x for x in self.sectionsvalue)]) if self.sectionsvalue else len(self.content)

    def text(self):
        print('  ' * self.level, "L%s" % self.level,
              self.name, "共%s行，共%s区域%s行" % (len(self.content), sum(len(x) for x in self.sectionsvalue), self.length()), ' 请检查行数'*(0 if len(self.content) == self.length()+self.loseline else 5))
        if self.attributes:
            # print(' '*self.level,  ' ', '='*10,  ' 属性 ', '='*10)
            print('  '*self.level,  ' '*4,  *["%s=[%s]" % (a, v)
                                              for a, v in zip(self.attributes, self.attributesvalue)])
        for s in self.sectionsvalue:
            for sn, sv in enumerate(s):
                if len(s) > 1:
                    print('  ' * sv.level, "L%s" % sv.level,
                          "%s/%s" % (sn+1, len(s)), sv.name,)
                sv.text()
        # if self.name == '教学内容要求和学时分配':
        #     print('=' * 100)
        #     printpt(self.content, self.level)
        #     print('=' * 100)
        # if not self.sections:
        #     printpt(self.content, self.level)

    def __str__(self):
        return "共%s行" % len(self.content)

    def createsection(self, sectionname, sectionconfig, content, loseline):
        section = Section(self, content, sectionconfig,
                          self.level, sectionname, loseline)
        return section

    def readsections(self):
        if isinstance(self.sections, list):
            for s in self.sections:
                sectionconfig = self.sectionconfig.get(s)
                enter = sectionconfig.get('enter')
                leave = sectionconfig.get('leave')
                loseline = sectionconfig.get('loseline', 0)
                enterline = -1 if enter else 0
                leaveline = -1
                sectionobjects = []

                for line, pt in enumerate(self.content):
                    value = find(leave, pt)
                    if leave and value != None:
                        leaveline = line + value[1]
                    if leaveline > enterline and enterline > -1:
                        # print(self.level, s, '找到一个数据', enterline,
                        #       leaveline, self.content[enterline].text, self.content[leaveline].text)

                        section = self.createsection(
                            s, sectionconfig, self.content[enterline:leaveline], loseline)
                        sectionobjects.append(section)
                        enterline = leaveline
                        leaveline = -1
                    value = find(enter, pt)
                    if enter and value != None:
                        enterline = line+value[1]
                if enterline > -1 and leaveline < 0:
                    # print(self.level, s, '没有结尾标识符', enterline, leaveline,
                    #       self.content[enterline].text, self.content[-1].text)

                    section = self.createsection(
                        s, sectionconfig, self.content[enterline:], loseline)

                    sectionobjects.append(section)
                self.sectionsvalue.append(sectionobjects)

    def readattributes(self):
        if isinstance(self.attributes, list):
            for attr in self.attributes:
                patt = self.sectionconfig.get(attr)
                for pt in self.content:
                    value = find(patt, pt)
                    if value != None:
                        self.attributesvalue.append(value[0])
                        break


if __name__ == "__main__":
    sc = Section(None, r"d:\\专业选修课.docx", fangan1, 0, '文档')
    print('\n'*5)
    print('='*50, '分析结果', '='*50)
    sc.text()
